package com.huwaiwai.lock.simple;

import java.util.Date;

/**
 * @author 歪大哥😁
 * @date 2020-04-22.
 */
public class SimpleAQSTest {

    public static void main(String[] args) throws Exception {
        testMainAndManyThreadAcquireAndRelease();
//        testTwoThreadAcquireAndRelease();
//        testOneThreadAcquireAndRelease();
    }

    static void testMainAndManyThreadAcquireAndRelease() throws Exception {
        SimpleAQS s = new SimpleAQS();
        s.acquire(1);
        System.out.println("主线程加锁:[state=" + s.state.get() + "],[time=" + new Date() + "]");
        Thread t1 = newThread(s);
        Thread t2 = newThread(s);
        Thread t3 = newThread(s);
        Thread t4 = newThread(s);
        Thread t5 = newThread(s);

        // 此时主线程持有锁 会阻塞子线程
        t1.start();
        t2.start();
        t3.start();
        t4.start();
        t5.start();

        // 主线程执行一秒后释放
        Thread.sleep(1000L);
        System.out.println("主线程释放锁:[state=" + s.state.get() + "],[time=" + new Date() + "]");
        t2.interrupt();
        s.release(1);

    }


    static void testTwoThreadAcquireAndRelease() throws Exception {
        SimpleAQS s = new SimpleAQS();
        s.acquire(1);
        System.out.println("主线程加锁:[state=" + s.state.get() + "],[time=" + new Date() + "]");
        Thread t = newThread(s);
        // 此时主线程持有锁 会阻塞子线程
        t.start();
        // 主线程执行一秒后释放
        Thread.sleep(1000L);
        System.out.println("主线程释放锁:[state=" + s.state.get() + "],[time=" + new Date() + "]");
        s.release(1);
    }

    static Thread newThread(SimpleAQS s) {
        return new Thread(() -> {
            String name = Thread.currentThread().getName();
            System.out.println("线程[" + name + "]准备获取:[state=" + s.state.get() + "],[time=" + new Date() + "]");
            s.acquire(1);
            System.out.println("线程[" + name + "]获取成功:[state=" + s.state.get() + "],[time=" + new Date() + "]");
            try {
                Thread.sleep(1000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("线程[" + name + "]获取成功1秒以后释放:[state=" + s.state.get() + "],[time=" + new Date() + "]");
            s.release(1);
        });
    }


    static void testOneThreadAcquireAndRelease() {
        SimpleAQS s = new SimpleAQS();
        s.acquire(1);
        System.out.println("第一次加锁:" + s.state.get());
        s.release(1);
        System.out.println("第一次解锁:" + s.state.get());
        s.acquire(2);
        System.out.println("第二次加锁:" + s.state.get());
        s.release(2);
        System.out.println("第二次解锁:" + s.state.get());
        s.acquire(3);
        System.out.println("第三次加锁:" + s.state.get());
        s.release(3);
        System.out.println("第三次解锁:" + s.state.get());
    }


}
